package com.ming.service.strategy.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.ming.config.properties.FileUploadProperties;
import com.ming.pojo.vo.FileUploadVO;
import com.ming.service.strategy.FileUploadStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 阿里云OSS文件上传策略实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(name = "file.type", havingValue = "oss")
public class OSSFileUploadStrategy implements FileUploadStrategy {

    private final FileUploadProperties fileUploadProperties;

    @Override
    public FileUploadVO uploadFile(MultipartFile file, String originalFileName, String contentType, long fileSize) throws IOException {
        // 1. 获取OSS配置
        FileUploadProperties.OSSConfig ossConfig = fileUploadProperties.getOss();

        // 2. 生成唯一文件名
        String fileExtension = getFileExtension(originalFileName);
        String uniqueFileName = generateUniqueFileName(fileExtension);

        // 3. 构建OSS文件路径
        String datePath = getDatePath();
        String ossFilePath = ossConfig.getPathPrefix() + datePath + "/" + uniqueFileName;

        // 4. 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(
                ossConfig.getEndpoint(),
                ossConfig.getAccessKeyId(),
                ossConfig.getAccessKeySecret()
        );

        try {
            // 5. 上传文件到OSS
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    ossConfig.getBucketName(),
                    ossFilePath,
                    file.getInputStream()
            );

            // 创建ObjectMetadata并设置文件类型
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(fileSize);
            if (contentType != null && !contentType.isEmpty()) {
                metadata.setContentType(contentType);
            }
            putObjectRequest.setMetadata(metadata);

            ossClient.putObject(putObjectRequest);

            // 6. 构建文件访问URL
            String fileUrl = ossConfig.getUrlPrefix() + "/" + ossFilePath;

            // 7. 构建返回结果
            FileUploadVO uploadVO = new FileUploadVO();
            uploadVO.setFileName(uniqueFileName);
            uploadVO.setOriginalFileName(originalFileName);
            uploadVO.setFileSize(fileSize);
            uploadVO.setContentType(contentType);
            uploadVO.setFileUrl(fileUrl);
            uploadVO.setUploadTime(LocalDateTime.now());
            uploadVO.setStoragePath(ossFilePath);

            log.info("OSS文件上传成功: {} -> {}", originalFileName, ossFilePath);
            return uploadVO;

        } catch (Exception e) {
            log.error("OSS文件上传失败: {}", e.getMessage());
            throw new IOException("OSS文件上传失败: " + e.getMessage(), e);
        } finally {
            // 8. 关闭OSS客户端
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public void deleteFile(String fileName) throws IOException {
        FileUploadProperties.OSSConfig ossConfig = fileUploadProperties.getOss();
        OSS ossClient = new OSSClientBuilder().build(
                ossConfig.getEndpoint(),
                ossConfig.getAccessKeyId(),
                ossConfig.getAccessKeySecret()
        );

        try {
            // 删除OSS文件
            ossClient.deleteObject(ossConfig.getBucketName(), fileName);
            log.info("OSS文件删除成功: {}", fileName);
        } catch (Exception e) {
            log.error("OSS文件删除失败: {}", e.getMessage());
            throw new IOException("OSS文件删除失败: " + e.getMessage(), e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public String getStorageType() {
        return "oss";
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        int lastDotIndex = filename.lastIndexOf('.');
        return lastDotIndex > 0 ? filename.substring(lastDotIndex) : "";
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFileName(String fileExtension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return timestamp + "_" + uuid + fileExtension;
    }

    /**
     * 获取日期路径（用于按日期分类存储）
     */
    private String getDatePath() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
    }
}